package com.beerandjesus.sportofkings.handicapper.dao;

import com.beerandjesus.sportofkings.handicapper.dao.aspect.TransactionBoundary;
import com.beerandjesus.sportofkings.handicapper.model.ProfileResult;
import com.beerandjesus.sportofkings.handicapper.model.ProfileResultImpl;
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.criterion.Projections;

import java.util.Date;
import java.util.List;


public class ProfileHistoryHibernateDAO extends AbstractHibernateDAO implements ProfileHistoryDAO {

    private static final Logger LOG = Logger.getLogger(ProfileHistoryHibernateDAO.class);

    @TransactionBoundary(datasources = Database.Datasource.HISTORY)
    public void buildDatabase() throws DAOException {
        dropAndCreate(DROP_TABLE + PROFILE_HISTORY, CREATE_TABLE + PROFILE_HISTORY + PROFILE_HISTORY_DEF, LOG);
        dropAndCreate("drop sequence " + PROFILE_HISTORY_SEQUENCE, "create sequence " + PROFILE_HISTORY_SEQUENCE, LOG);
    }

    @TransactionBoundary(datasources = Database.Datasource.HISTORY)
    public void save(ProfileResult profileResult) {
        getSession().save(profileResult);
    }

    @SuppressWarnings("unchecked")
    public List<ProfileResult> findByRace(String trackCode, Date raceDate, Integer raceNumber) {
        String query = "from ProfileResultImpl a where a.trackCode = :trackCode and " +
                "a.raceDate = :raceDate and a.raceNumber = :raceNumber";
        Query q = getSession().createQuery(query);
        q.setString("trackCode", trackCode);
        q.setDate("raceDate", raceDate);
        q.setInteger("raceNumber", raceNumber);
        return q.list();
    }

    @SuppressWarnings("unchecked")
    public List<ProfileResult> findByHorseName(String horseName) {
        String query = "from ProfileResultImpl a where a.horseName = :horseName";
        Query q = getSession().createQuery(query);
        q.setString("horseName", horseName);
        return q.list();
    }

    public ProfileResult find(ProfileResult toFind) {
        String query = "from ProfileResultImpl a where " +
                "a.horseName = :horseName and " +
                "a.trackCode = :trackCode and " +
                "a.raceDate = :raceDate and " +
                "a.raceNumber = :raceNumber and " +
                "a.analysisProfile = :analysisProfile";
        Query q = getSession().createQuery(query);
        q.setString("horseName", toFind.getHorseName());
        q.setString("trackCode", toFind.getTrackCode());
        q.setDate("raceDate", toFind.getRaceDate());
        q.setInteger("raceNumber", toFind.getRaceNumber());
        q.setString("analysisProfile", toFind.getAnalysisProfile());
        return (ProfileResult) q.uniqueResult();
    }

    public int getCount() {
        Long count = (Long) getSession().createCriteria(ProfileResultImpl.class).setProjection(Projections.rowCount()).uniqueResult();
        return count.intValue();
    }
}
